<?php
/**
 * Created by PhpStorm.
 * User: Korbin
 * Date: 2018/11/10
 * Time: 11:17
 */

namespace app\script\command;

use app\common\model\Job;
use app\common\model\News;
use app\common\model\NewsContent;
use app\common\model\NewsType;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;

class TopbuzzNews extends Base
{

    private $listKey = 'items';//获取数据区域
    private $startUrl = 'https://i16-tb.isnssdk.com/api/771/stream?tab=General&count=20&min_behot_time=1.543044116999E9&sign=9748f69c2d6858e01564f016b6f1ddf48d18dee5&timestamp=1543044114&logo=topbuzz&gender=0&bv_is_auto_play=0&youtube=0&manifest_version_code=771&app_version=7.7.1&iid=6627270542972012294&gaid=260db64c-b2b6-48d3-80c8-26a99d4f7e30&original_channel=gp&channel=gp&fp=2lT_PrqrcrDqFlxScSU1LMGtLWTZ&device_type=MI+4LTE&language=en&resolution=1920*1080&openudid=813fee40fc7f1867&update_version_code=7710&sys_language=en&sys_region=us&os_api=23&tz_name=Asia%2FShanghai&tz_offset=28800&dpi=480&brand=Xiaomi&ac=WIFI&device_id=6623886569499608582&os=android&os_version=6.0.1&version_code=771&hevc_supported=1&device_brand=Xiaomi&device_platform=android&sim_region=&region=us&aid=1106';
    private $type='For you';
    /**
     * 设置执行名称及配置传入参数、脚本描述
     */
    protected function configure()
    {
        //设置执行名称
        $this->setName('topbuzzNews')
            ->addOption('job', 'j', Option::VALUE_OPTIONAL)
            ->setDescription('Run all the time');
    }

    /*********************公用验证部分************************************/
    /*
     * 执行脚本任务
     *
     * @param Input $input
     * @param Output $output
     */
    protected function execute(Input $input, Output $output)
    {
        $job = $input->getOption('job');
        if (empty($job)) {
            $output->writeln('请传入执行任务ID：' . date('Y-m-d H:i:s'));
            exit();
        }

        $output->writeln('脚本开始：' . date('Y-m-d H:i:s'));
        $jobModel = new Job();
        $jobInfo = $jobModel->where(['id' => $job])->find();//获取任务配置信息
        if (empty($jobInfo)) {
            $output->writeln('任务ID不存在：' . date('Y-m-d H:i:s'));
            exit();
        } else {
            $jobInfo = $jobInfo->toArray();
        }
//        $this->redis->hSet('job_status',$job,1);
        $jobRedisInfo = $this->redis->hGet('jobHash', $job);//获取任务redis记录
        if (empty($jobRedisInfo)) {
            $jobRedisData = [
                'planned_quantity' => $jobInfo['planned_quantity'],
                'real_quantity' => (empty($jobInfo['real_quantity']) ? 0 : $jobInfo['real_quantity']),
                'shortvideo_num' => (empty($jobInfo['shortvideo_num']) ? 0 : $jobInfo['shortvideo_num']),
                'smallvideo_num' => (empty($jobInfo['smallvideo_num']) ? 0 : $jobInfo['smallvideo_num']),
                'finsh_time' => '',
            ];
        } else {
            $jobRedisData = json_decode($jobRedisInfo, true);
            $jobRedisData['planned_quantity'] = $jobInfo['planned_quantity'];
        }
        $newsTypeId = [];
        $this->createType($jobInfo,$newsTypeId);
        //开始循环执行采集任务
        while (true) {
            //采集开始执行验证采集开关是否打开
            $jobStatus = $this->redis->hGet('job_status', $job);
            if ($jobStatus != 1) {
                break;//采集开关关闭时跳出循环结束脚本执行
            }
            $result = $this->getApiData();//获取采集源结果
            //验证是否有相应的采集数据
            if (is_array($result)&& array_key_exists($this->listKey, $result)) {
                $lists = $result[$this->listKey];
            } else {
                $output->writeln($this->getName() . '采集源服务器出错或找不到采集信息！'. date('Y-m-d H:i:s'));
                continue;
            }
            //开始拼装数据
            $insertData = [];
            if (!empty($lists)) {
                $this->createData($lists, $jobInfo, $jobRedisData, $insertData,$newsTypeId[$this->type]);//对源数据进行对应入库
                if (!empty($insertData)) {
                    //当实际采集数据大于等于计划采集数据量时设置redis开关值
                    if (($jobRedisData['planned_quantity'] - $jobRedisData['real_quantity']) <= 0) {
                        $this->redis->hSet('job_status', $job, 2);//正常完成值为2
                        $jobRedisData['finsh_time'] = date('Y-m-d H:i:s');//正常完成时间记录
                        $jobModel->save(['job_status'=>2,'status_time'=>date('Y-m-d H:i:s')],['id'=>$job]);
                    }
                    $this->redis->hSet('jobHash', $job, json_encode($jobRedisData));
                    $output->writeln('【' . $this->getName() . '采集成功】本次采集入库数据条数为【' . count($insertData) . '】'. date('Y-m-d H:i:s'));
                } else {
                    $output->writeln('【' . $this->getName() . '执行成功】本次采集无符合要求的数据入库!'. date('Y-m-d H:i:s'));
                }
            } else {
                $output->writeln('【'.$this->getName().'请求成功】本次请求无返回正确数据!'.date('Y-m-d H:i:s'));
                continue;
            }


            //间隔随机时间
            $sleep = rand(5, 10);
            sleep($sleep);
        }

        $output->writeln($this->getName().'任务执行完毕：' . date('Y-m-d H:i:s'));
    }
    /*********************公用验证部分************************************/

    /**
     * 组装url进行数据获取
     * @param $url
     * @return mixed
     */
    private function getApiData()
    {
        $result = curl_get_https($this->startUrl);
        $result = json_decode($result, true);
        return $result['data'];
    }

    /**
     * 采集数据拼装入库
     *
     * @param $lists
     * @param $jobInfo
     * @param $jobRedisData
     * @param $insertData
     * @param $typeId
     */
    private function createData($lists, $jobInfo, &$jobRedisData, &$insertData,$typeId)
    {
        $news =  new News();
        $newContent=new NewsContent();

        $contentInsertData=[];
        $updateData = [];
        $dataIds = [];
        foreach ($lists as $val) {
            if(!is_array($val)){
                continue;
            }
            $data = [];
            if(isset($val['video'])){
                continue;
            }
            //视频评论、点赞、收藏、分享数
            $data['thumb_num'] = array_key_exists('user_digg',$val)?$val['user_digg']:0;
            $data['comment_num'] = isset($val['comment_count'])?$val['comment_count']:0;
            $data['watch_num'] = isset($val['read_count'])?$val['read_count']:0;
            $data['share_num'] = isset($val['share_count'])?$val['share_count']:0;

            //验证视频是否符合采集需求
            $validateRes = $this->validateNum($data,$jobInfo);
            if ($validateRes == false) {
                continue;
            }
            //平台信息【可不动】
            $data['job_id'] = $jobInfo['id'];
            $data['language'] = $jobInfo['lang'];
            $data['country'] = $jobInfo['country'];
            $data['platform'] = $jobInfo['platform'];
            $data['create_by'] = $jobInfo['create_by'];
            $data['create_date'] = date('Y-m-d H:i:s');
            $data['update_by'] = $jobInfo['update_by'];
            $data['update_date'] = date('Y-m-d H:i:s');
            $data['remarks'] = '';

            //新闻信息
            $data['uni'] = $val['item_id'];//第三方视频唯一ID


            if (in_array($data['uni'],$dataIds,true)) {
                continue;
            }
            array_push($dataIds,$data['uni']);
            $data['title'] = $val['title'];//新闻标题
            $data['cover_img'] = isset($val['middle_image'])?$val['middle_image']['url_list'][0]['url']:(isset($val['image_list'])?$val['image_list'][0]['url_list'][0]['url']:'');//封面
            $data['cover_show_type'] = '';//封面类型

            $data['author_avatar'] = isset($val['url_list'])?$val['url_list']['avatar']['uri']:'';//作者头像
            $data['author_name'] = isset($val['url_list'])?$val['url_list']['name']:'';//作者姓名
            $data['create_time'] = $val['publish_time'];//创建时间
            $data['update_time'] = $val['publish_time'];//更新时间
            $data['href']=$val['display_url'];
            $data['source']=$val['article_url'];
            $data['visit_count'] = $val['read_count'];//访问数量
            $data['type_id'] = $typeId;//分类id
            $data['like_count'] = $val['like_count'];//点赞数量
            $data['comment_count'] = $val['recommend_count'];//留言个数
            $data['unlike_count'] = 0;//
            $data['unlike_enable'] =0;//是否允许不喜欢
            $data['can_comment'] = 1;//是否允许评论,默认为1允许',
            $data['share_count'] = $val['share_count'];//分享个数
            $data['listorder'] = 0;//排序
            $data['status'] = 1;//状态:1显示,2不显示



            $dataContent['id'] = com_create_guid();//生成唯一UUID
            $dataContent['content']='';
            $dataContent['update_time']=time();
            $dataContent['create_by']=$data['create_by'];
            $dataContent['create_date']=$data['create_date'];
            $dataContent['update_by']=$data['update_by'];

            $dataContent['remarks']='';
            //判断是否 已经存在
            $isExist = $news->field('id')->where([
                'uni' => $data['uni']
            ])->find();
            if ($isExist) {
                //continue;
                $data['id'] = $isExist['id'];
                $updateData[] = $data;
            }else{
                $data['id'] = com_create_guid();//生成唯一UUID
                $dataContent['news_id']=$data['id'];;
                $contentInsertData[]=$dataContent;
                $jobRedisData['real_quantity'] += 1;//实际采集数量+1
                $insertData[] = $data;
            }
        }
        $news->allowField(true)->isUpdate(true)->saveAll($updateData);
        $news->allowField(true)->isUpdate(false)->saveAll($insertData,false);
        $newContent->allowField(true)->isUpdate(false)->saveAll($contentInsertData, false);
    }

    /**
     * 验证采集数据是否符合条件
     *
     * @param $data
     * @param $jobInfo
     * @return bool
     */
    private function validateNum($data,$jobInfo){
        $res = true;
        $keys = array_keys($data);
        foreach ($keys as $val){
            if($jobInfo[$val]>$data[$val]){
                $res = false;
                break;
            }
        }
        return $res;
    }

    /**
     * 创建平台类型
     *
     * @param $jobInfo
     * @param $newsTypeId
     */
    private function createType($jobInfo,&$newsTypeId){
        $newType=new NewsType();
        $newsTypeId = [];
        $newsTypeId = $newType->where(['platform'=>$jobInfo['platform']])->column('name,id');
        if(empty($newsTypeId)){
            $insertData=[];
            $data['id']=com_create_guid();//生成唯一UUID
            $data['name']=$this->type;
            $data['platform']=$jobInfo['platform'];
            $data['type']=2;
            $data['status']=1;
            $data['create_time']=time();
            $data['sort']=0;
            $data['is_hot']=1;
            $data['create_by']=$jobInfo['create_by'];
            $data['create_date']=$jobInfo['create_date'];
            $data['update_by']=$jobInfo['update_by'];
            $data['update_date']=$jobInfo['update_date'];
            $insertData[]=$data;
            $newsTypeId[$data['name']] = $data['id'];
            $newType->allowField(true)->insertAll($insertData);
        }
    }

}